/*
 * Copyright (C) 2014 Nathan Templon
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package unit.quantity;

import exception.DissimilarUnitException;
import unit.Unit;

/**
 *
 * @author Hortator
 */
public class UnitQuantity {
    
    public UnitQuantity( double value, Unit unit ) {
        this.unit = unit;
        this.value = value;
    }
    
    
    public Unit unit() {
        return unit;
    }
    
    
    public double value() {
        return value;
    }
    
    
    public UnitQuantity times(UnitQuantity other) {
        return new UnitQuantity(this.value * other.value(), this.unit.times(other.unit()));
    }
    
    
    public UnitQuantity dividedBy(UnitQuantity other) {
        return new UnitQuantity(this.value / other.value(), this.unit.dividedBy(other.unit()));
    }
    
    
    public UnitQuantity compressToBase() {
        Unit base = this.unit.compressToBase();
        return new UnitQuantity(this.unit.scaleToBase() * this.value * base.scale(), base.scaleless());
    }
    
    
    public UnitQuantity toUnit(Unit other) {
        if(!unit.isSimilar(other)) {
            throw new DissimilarUnitException("The units could not be converted.");
        }
        else {
            return new UnitQuantity(this.value * unit.scaleTo(other), other);
        }
    }
    
    
    public UnitQuantity plus(UnitQuantity other) {
        if (!unit.isSimilar(other.unit())) {
            throw new DissimilarUnitException("UnitQuantity addition can only happen with unit quantities that are similar.");
        }
        double newValue = this.value + other.toUnit(this.unit).value;
        return new UnitQuantity(newValue, this.unit);
    }
    
    
    public UnitQuantity minus(UnitQuantity other) {
        if (!unit.isSimilar(other.unit())) {
            throw new DissimilarUnitException("UnitQuantity subtraction can only happen with unit quantities that are similar.");
        }
        double newValue = this.value - other.toUnit(this.unit).value;
        return new UnitQuantity(newValue, this.unit);
    }
    
    
    public UnitQuantity scalarMultiply(double d) {
        return new UnitQuantity(d * this.value, this.unit);
    }
    
    
    @Override
    public String toString() {
        return value + " " + unit.name();
    }
    
    
    private Unit unit;
    private double value;
    
}
